package admin

import (
	"context"
	"encoding/json"
	"strconv"

	"suci-go-zero/common/xerr"
	"suci-go-zero/internal/model"
	"suci-go-zero/internal/svc"
	"suci-go-zero/internal/types"

	"github.com/pkg/errors"
	"github.com/zeromicro/go-zero/core/logx"
	"github.com/zeromicro/go-zero/core/stores/sqlx"
)

type MenuUpLogic struct {
	logx.Logger
	ctx    context.Context
	svcCtx *svc.ServiceContext
}

func NewMenuUpLogic(ctx context.Context, svcCtx *svc.ServiceContext) *MenuUpLogic {
	return &MenuUpLogic{
		Logger: logx.WithContext(ctx),
		ctx:    ctx,
		svcCtx: svcCtx,
	}
}

func (l *MenuUpLogic) MenuUp(req *types.MenuItemUp) error {
	id, _ := strconv.Atoi(req.Id)
	err := l.svcCtx.Models.Menu.Trans(l.ctx, func(context context.Context, session sqlx.Session) error {
		rb := l.svcCtx.Models.MenuApi.RowBuilder().Where("menu_id=?", id)
		apiLists, err := l.svcCtx.Models.MenuApi.FindAll(l.ctx, rb, "")
		if err != nil {
			return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "")
		}
		//删除原来的apilist
		for _, api := range apiLists {
			err := l.svcCtx.Models.MenuApi.DeleteSoft(l.ctx, session, api)
			if err != nil {
				return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "")
			}
		}
		//插入现在的apiList
		for _, apiItem := range req.ApiList {
			_, err := l.svcCtx.Models.MenuApi.Insert(l.ctx, session, &model.AdminMenuApi{
				Code:   apiItem.Code,
				Url:    apiItem.Url,
				MenuId: apiItem.MenuId,
			})
			if err != nil {
				return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "")
			}
		}

		m, err := l.svcCtx.Models.Menu.FindOne(l.ctx, int64(id))
		if err != nil && err != model.ErrNotFound {
			return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "")
		}

		pid, _ := strconv.Atoi(req.Pid)
		m.ParentId = int64(pid)
		m.Name = req.Name
		m.Path = req.Path
		meta, _ := json.Marshal(req.Meta)
		m.Meta = string(meta)
		m.Component = req.Component
		m.Redirect = req.Redirect
		m.Sort = req.Sort

		err = l.svcCtx.Models.Menu.UpdateWithVersion(l.ctx, session, m)

		if err != nil {
			return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "")
		}

		return nil
	})

	return err
}
